/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.huawei.spare.part.replace.views.replace.smm;

import com.huawei.spare.part.replace.framework.SmartContentPresenter;
import com.huawei.spare.part.replace.framework.SmartDataBus;
import com.huawei.spare.part.replace.framework.SmartRouter;
import com.huawei.spare.part.replace.models.Configs;
import com.huawei.spare.part.replace.models.Replacement;
import com.huawei.spare.part.replace.rx.RxUtils;
import com.huawei.spare.part.replace.utils.SSHHelper;
import com.huawei.spare.part.replace.views.widgets.Alerts;
import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.scene.control.PasswordField;
import javafx.scene.control.TextField;
import net.schmizz.sshj.SSHClient;
import org.controlsfx.validation.Severity;
import org.controlsfx.validation.ValidationSupport;
import org.controlsfx.validation.Validator;
import org.controlsfx.validation.decoration.GraphicValidationDecoration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.concurrent.Callable;

import static com.huawei.spare.part.replace.Constants.PatternIPV4;

/**
 * @author Woo
 */
public class SmmPresenter extends SmartContentPresenter {

    private static final Logger log = LoggerFactory.getLogger(SmmPresenter.class);

    @FXML TextField smmHost;
    @FXML TextField smmUsername;
    @FXML PasswordField smmPassword;
//    @FXML TextField solUsername;
//    @FXML PasswordField solPassword;

    @Override
    public void initialize() {
        addFormValidation();
        Platform.runLater(() -> {
            final Configs configs = SmartDataBus.get().getConfigs();
            smmHost.textProperty().setValue(configs.getDefaultHost());
            smmUsername.textProperty().setValue(configs.getDefaultUsername());
//            solUsername.textProperty().setValue(configs.getDefaultUsername());
            smmPassword.textProperty().setValue(configs.getDefaultPassword());
//            solPassword.textProperty().setValue(configs.getDefaultPassword());
            smmHost.requestFocus();
        });
    }

    private void addFormValidation() {
        ValidationSupport support = new ValidationSupport();
        support.setValidationDecorator(new GraphicValidationDecoration());

        final Validator<Object> notEmpty = Validator.createEmptyValidator(getString("common.validate.not.empty"));
        final Validator<String> ipV4 = Validator.createRegexValidator(getString("common.validate.ipv4"), PatternIPV4, Severity.ERROR);

        support.registerValidator(smmHost, notEmpty);
        support.registerValidator(smmHost, ipV4);
        support.registerValidator(smmUsername, notEmpty);
        support.registerValidator(smmPassword, notEmpty);
//        support.registerValidator(solUsername, notEmpty);
//        support.registerValidator(solPassword, notEmpty);

        support.invalidProperty().addListener((observable, oldValue, newValue) -> SmartRouter.get().nextStepButton().setDisable(newValue));
    }

    @Override
    public Observable<Boolean> onFinish() {
        Replacement.SmmAuth auth = new Replacement.SmmAuth();
        auth.setSmmHost(smmHost.getText());
        auth.setSmmUsername(smmUsername.getText());
        auth.setSmmPassword(smmPassword.getText());
        auth.setSolUsername(smmUsername.getText());
        auth.setSolPassword(smmPassword.getText());
        SmartDataBus.get().replacement().setSmmAuth(auth);

        loading("smm.authentication.validating", false);
        return Observable.defer(new Callable<ObservableSource<Boolean>>() {
            @Override
            public ObservableSource<Boolean> call() {
                try (SSHClient sshClient = SSHHelper.newSSHClient(auth.getSmmHost(), auth.getSmmUsername(), auth.getSmmPassword())) {
                    final boolean authenticated = sshClient.isAuthenticated();
                    return Observable.just(authenticated);
                } catch (IOException e) {
                    log.info("SSH [{}] auth failed, reason: {}", auth.getSmmHost(), e.getMessage());
                    return Observable.just(false);
                }
            }
        }).compose(RxUtils.<Boolean>applySchedulers()).doOnNext((result) -> {
            dismissLoading();
            if (!result) {
                Alerts.error("smm.connect.failed.title", "smm.connect.failed.content");
            }
        });

    }
}
